package pizarra;
import java.io.IOException;
import java.io.Serializable;
import java.util.Hashtable;
import java.util.List;

import javax.swing.SwingUtilities;

import mobilefeel.AndroidDevice;
import mobilefeel.DeviceListener;
import mobilefeel.MobileFeel;
import mobilefeel.dto.TouchEvent;
import mobilefeel.touchscreen.OnTouchListener;
import mobilefeel.touchscreen.View;
import mobilefeel.touchscreen.ViewListener;



public class PizarraMultitouch implements DeviceListener, ViewListener, OnTouchListener {

	private MobileFeel mobileFeel;
	private Hashtable<AndroidDevice, Pizarra> pizarras;
	private Hashtable<AndroidDevice, View> pizarrasAndroid;
	private Controlador controlador;
	
	public PizarraMultitouch(Controlador c){
		pizarras = new Hashtable<AndroidDevice, Pizarra>();
		pizarrasAndroid = new Hashtable<AndroidDevice, View>();
		controlador = c;
		
		mobileFeel = new MobileFeel();
		mobileFeel.addDeviceListener(this);
	}
	
	public void iniciar(int puerto) throws IOException {
		mobileFeel.listen(puerto);
	}

	public void nuevaPizarra(AndroidDevice device, Pizarra p) {
		pizarras.put(device, p);
		try {
			pizarrasAndroid.get(device).addOnTouchListener(this);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public void onDeviceConnected(AndroidDevice device) {
		controlador.doDispositivoConectado(device.toString());
		
		device.getTouchScreen().addViewListener(this);
	}

	@Override
	public void onDeviceDisconnected(AndroidDevice device) {	
		controlador.doDispositivoDesconectado(device.toString(), mobileFeel.getDevices().size());
	}

	@Override
	public void onViewRegistered(AndroidDevice device, View view) {
		if (view.getName().equals("Pizarra"))
			pizarrasAndroid.put(device, view);
	}
	
	public int getAnchoPizarra(AndroidDevice device) {
		return pizarrasAndroid.get(device).getWidth();
	}
	
	public int getAltoPizarra(AndroidDevice device) {
		return pizarrasAndroid.get(device).getHeight();
	}
	
	@Override
	public void onTouch(final View v, final TouchEvent e) {
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				Pizarra pizarra = pizarras.get(v.getAndroidDevice());
				if (pizarra != null) {
					switch(e.getAction()){
					case TouchEvent.ACTION_DOWN:
						Linea linea = new Linea(e.getPointerId(0));
						linea.setColor(pizarra.getColor(0));
						linea.addPunto(e.getCurrentByIndex(0));
						pizarra.nuevaLinea(linea);
						pizarra.getVistaPizarra().repaint();
						break;
					
					case TouchEvent.ACTION_POINTER_DOWN:
						Linea lineaPointerDown = new Linea(e.getActionPointer());
						lineaPointerDown.setColor(pizarra.getColor(e.getActionPointer()));
						lineaPointerDown.addPunto(e.getCurrentById(e.getActionPointer()));
						pizarra.nuevaLinea(lineaPointerDown);
						
						for(int pointer = 0; pointer < e.getPointerCount(); pointer++){
							Linea lineaMove = pizarra.getUltimaLinea(e.getPointerId(pointer));
							if (lineaMove != null && e.getPointerId(pointer) != e.getActionPointer()) {
								lineaMove.addPunto(e.getCurrentById(lineaMove.getPointer()));
							}
						}
						pizarra.getVistaPizarra().repaint();
						break;
						
					case TouchEvent.ACTION_MOVE:
						for(int pointer = 0; pointer < e.getPointerCount(); pointer++){
							Linea lineaMove = pizarra.getUltimaLinea(e.getPointerId(pointer));
							if (lineaMove != null) {
								for(int i = 0; i < e.getHistorySize(); i++)
									lineaMove.addPunto(e.getHistoricalById(lineaMove.getPointer(), i));			
								lineaMove.addPunto(e.getCurrentById(lineaMove.getPointer()));
								}
						}
						pizarra.getVistaPizarra().repaint();
						break;
					}
				}
			}
		});
	}


	@Override
	public void onCustomDataReceived(AndroidDevice device, String text, Serializable object) {
		if(text.equals("menu") && ((String)object).equals("borrar")) {
			Pizarra pizarra = pizarras.get(device);
			if (pizarra != null) {
				pizarra.borrar();
				pizarra.getVistaPizarra().repaint();
			}
		}
	}

	public void detener() throws IOException {
		mobileFeel.stopListening();
	}

	public List<AndroidDevice> getDispositivosConectados() {
		return mobileFeel.getDevices();
	}

}
